﻿using System;
using System.Runtime.InteropServices;
//Copyright (C) 2003 Microsoft Corporation
//All rights reserved.
//
//THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
//EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
//MERCHANTIBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//
//Date: January 2003
//Author: Duncan Mackenzie
//http://www.gotdotnet.com/Community/User/viewprofile.aspx?userid=00011A674C38C375
//
//Requires the release version of .NET Framework (1.0)

//http://msdn.microsoft.com/en-us/library/aa302353.aspx

using System.Text;

namespace CredentialManager
{

  public class CredUI
  {
    private const int MAX_USER_NAME = 100;
    private const int MAX_PASSWORD = 100;

    private const int MAX_DOMAIN = 100;
    public static CredUIReturnCodes PromptForCredentials(ref CREDUI_INFO creditUI, string targetName, int netError, ref string userName, ref string password, ref bool save, CREDUI_FLAGS flags)
    {

      int saveCredentials = 0;
      StringBuilder user = new StringBuilder(MAX_USER_NAME);
      StringBuilder pwd = new StringBuilder(MAX_PASSWORD);
      saveCredentials = Convert.ToInt32(save);
      creditUI.cbSize = Marshal.SizeOf(creditUI);
      CredUIReturnCodes result = default(CredUIReturnCodes);
      result = CredUIPromptForCredentials(ref creditUI, targetName, IntPtr.Zero, netError, user, MAX_USER_NAME, pwd, MAX_PASSWORD, ref saveCredentials, flags);
      save = Convert.ToBoolean(saveCredentials);
      userName = user.ToString();
      password = pwd.ToString();
      return result;
    }

    public static CredUIReturnCodes ParseUserName(string userName, ref string userPart, ref string domainPart)
    {

      StringBuilder user = new StringBuilder(MAX_USER_NAME);
      StringBuilder domain = new StringBuilder(MAX_DOMAIN);
      CredUIReturnCodes result = default(CredUIReturnCodes);
      result = CredUIParseUserName(userName, user, MAX_USER_NAME, domain, MAX_DOMAIN);
      userPart = user.ToString();
      domainPart = domain.ToString();
      return result;
    }

    public static CredUIReturnCodes ConfirmCredentials(string target, bool confirm)
    {
      return CredUIConfirmCredentials(target, confirm);
    }
    [DllImport("credui", EntryPoint = "CredUIPromptForCredentialsW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]


    private static extern CredUIReturnCodes CredUIPromptForCredentials(ref CREDUI_INFO creditUR, string targetName, IntPtr reserved1, int iError, StringBuilder userName, int maxUserName, StringBuilder password, int maxPassword, ref int iSave, CREDUI_FLAGS flags);
    [DllImport("credui", EntryPoint = "CredUIParseUserNameW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]

    private static extern CredUIReturnCodes CredUIParseUserName(string userName, StringBuilder user, int userMaxChars, StringBuilder domain, int domainMaxChars);
    [DllImport("credui", EntryPoint = "CredUIConfirmCredentialsW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]

    private static extern CredUIReturnCodes CredUIConfirmCredentials(string targetName, bool confirm);
    [DllImport("Gdi32", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]

    public static extern bool DeleteObject(IntPtr hObject);

  }


  [Flags()]
  public enum CREDUI_FLAGS
  {
    INCORRECT_PASSWORD = 0x1,
    DO_NOT_PERSIST = 0x2,
    REQUEST_ADMINISTRATOR = 0x4,
    EXCLUDE_CERTIFICATES = 0x8,
    REQUIRE_CERTIFICATE = 0x10,
    SHOW_SAVE_CHECK_BOX = 0x40,
    ALWAYS_SHOW_UI = 0x80,
    REQUIRE_SMARTCARD = 0x100,
    PASSWORD_ONLY_OK = 0x200,
    VALIDATE_USERNAME = 0x400,
    COMPLETE_USERNAME = 0x800,
    PERSIST = 0x1000,
    SERVER_CREDENTIAL = 0x4000,
    EXPECT_CONFIRMATION = 0x20000,
    GENERIC_CREDENTIALS = 0x40000,
    USERNAME_TARGET_CREDENTIALS = 0x80000,
    KEEP_USERNAME = 0x100000
  }

  public enum CredUIReturnCodes : int
  {
    NO_ERROR = 0,
    ERROR_CANCELLED = 1223,
    ERROR_NO_SUCH_LOGON_SESSION = 1312,
    ERROR_NOT_FOUND = 1168,
    ERROR_INVALID_ACCOUNT_NAME = 1315,
    ERROR_INSUFFICIENT_BUFFER = 122,
    ERROR_INVALID_PARAMETER = 87,
    ERROR_INVALID_FLAGS = 1004
  }

  public struct CREDUI_INFO
  {
    public int cbSize;
    public IntPtr hwndParent;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pszMessageText;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pszCaptionText;
    public IntPtr hbmBanner;
  }

}

